/*
 * Copyright (C) 2004, Velocityme Partnership
 * PersonActions.java
 *
 * Created on 28 September 2004, 07:46
 */

package com.velocityme.www.interfaces.nodeactions;

import com.velocityme.entity.Node;
import com.velocityme.entity.Person;
import com.velocityme.entity.State;
import com.velocityme.entity.Activity;
import com.velocityme.entity.Time;
import com.velocityme.enums.Permission;
import com.velocityme.session.ContactDetailLocal;
import com.velocityme.session.KeyLocal;
import com.velocityme.session.NodeLocal;
import com.velocityme.session.PersonLocal;
import com.velocityme.session.SearchLocal;
import com.velocityme.session.StateLocal;
import com.velocityme.www.actionforms.PersonTimeActionForm;
import com.velocityme.www.actionforms.TimeActionForm;
import com.velocityme.www.actionforms.nodeactionforms.PersonActionForm;
import com.velocityme.www.dto.IdName;
import com.velocityme.www.dto.IntegerString;
import com.velocityme.www.dto.TimeDTO;
import com.velocityme.www.interfaces.ShowNodeAction;
import com.velocityme.www.utility.NodeUtil;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

/**
 *
 * @author  Robert
 */
public class PersonActions extends ContactableActions {

    /** Creates a new instance of PersonActions */
    public PersonActions() {
    }

    @Override
    public ActionForward show(ActionMapping mapping,
                              ActionForm form,
                              HttpServletRequest request,
                              HttpServletResponse response) throws Exception {
        Long nodeId = (Long)request.getAttribute("nodeId");
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Person person = lookupPersonBean().findPerson(key, nodeId);
        session.setAttribute("person", person);
        return mapping.findForward("ACTION_DISPLAY");
    }

    public ActionForward showTodayTime(ActionMapping mapping,
                                       ActionForm form,
                                       HttpServletRequest request,
                                       HttpServletResponse response) throws Exception {
        Long nodeId = (Long)request.getAttribute("nodeId");
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        PersonTimeActionForm personTimeAF = new PersonTimeActionForm();
        personTimeAF.setNodeId(nodeId);
        personTimeAF.setDate(new Date());
        return showTime(mapping, personTimeAF, request, response);
    }

    public ActionForward showTime(ActionMapping mapping,
                                  ActionForm form,
                                  HttpServletRequest request,
                                  HttpServletResponse response) throws Exception {
        PersonTimeActionForm personTimeAF = (PersonTimeActionForm)form;
        Long nodeId = personTimeAF.getNodeId();
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Person person = key.getPerson();//lookupPersonBean().findPerson(key, nodeId);
        ShowNodeAction.setupTreeDisplay(session, person, "Person Time");
        Calendar start = Calendar.getInstance();
        Calendar stop = Calendar.getInstance();
        start.setTime(personTimeAF.getDate());
        stop.setTime(personTimeAF.getDate());
        stop.add(Calendar.DATE, 1);
        String btnSubmit = request.getParameter("btnSubmit");
        if (btnSubmit != null) {
            if (btnSubmit.equals("<")) {
                start.add(Calendar.DATE, -1);
                stop.add(Calendar.DATE, -1);
            }
            if (btnSubmit.equals(">")) {
                start.add(Calendar.DATE, 1);
                stop.add(Calendar.DATE, 1);
            }
        }
        personTimeAF.setDate(start.getTime());
        Collection<TimeDTO> timeDTOs = new ArrayList<TimeDTO>();
        long totalDuration = 0;
        for (Time time: lookupPersonBean().getPersonTimes(key, person, start.getTime(), stop.getTime())) {
            Set<Permission> assignedPermissions = lookupSearchBean().getAssignedPermissions(key, time.getActivity());
            boolean isEditable = assignedPermissions.contains(Permission.TIME_EDIT);
            boolean isDeletable = assignedPermissions.contains(Permission.TIME_DELETE);
            long timeId = time.getId();
            long taskId = time.getActivity().getId();
            String taskName = time.getActivity().getName();
            String personName = time.getPerson().getName();
            String description = time.getDescription();
            String stateName = time.getState().getName();
            Date startTime = time.getStartTime();
            Date stopTime = time.getStopTime();
            long duration = time.getStopTime().getTime() - time.getStartTime().getTime();
            totalDuration += duration;
            int remainingDuration_min = time.getRemainingDuration_min();
            timeDTOs.add(new TimeDTO(isEditable, isDeletable, timeId, taskId, taskName, personName, description, stateName, startTime, stopTime, duration, remainingDuration_min));
            start.setTime(time.getStopTime());
        }
        session.setAttribute("personTimes", timeDTOs);
        session.setAttribute("personDuration", new Long(totalDuration));
        session.setAttribute("years", NodeUtil.getInstance().getYears());
        session.setAttribute("months", NodeUtil.getInstance().getMonths());
        session.setAttribute("days", NodeUtil.getInstance().getDays());
        session.setAttribute("personTimeAF", personTimeAF);
        session.setAttribute("timeValue", new Time());
        showCreatePersonTime(mapping, form, request, response, start.getTime());
        return mapping.findForward("ACTION_DISPLAY");
    }

    public class PersonTimeActionForm2 {
        private Collection m_statePairs = new ArrayList();
        private Collection m_percentageComplete = new ArrayList();
        private Collection m_durationDays = new ArrayList();
        private Collection m_durationHours = new ArrayList();
        private Collection m_durationMins = new ArrayList();

        public void add(Byte percentageComplete, int totalMins, Collection statePairs) {
            m_percentageComplete.add(percentageComplete);
            m_durationDays.add(new Integer(totalMins / (8 * 60)));
            m_durationHours.add(new Integer((totalMins / 60) % 8));
            m_durationMins.add(new Integer(totalMins % 60));
            m_statePairs.add(statePairs);
        }

        public Collection getStatePairs() { return m_statePairs; }

        public Collection getPercentageCompletes() { return m_percentageComplete; }

        public Collection getDurationDays() { return m_durationDays; }

        public Collection getDurationHours() { return m_durationHours; }

        public Collection getDurationMins() { return m_durationMins; }
    }

    public void showCreatePersonTime(ActionMapping mapping,
                                     ActionForm form,
                                     HttpServletRequest request,
                                     HttpServletResponse response,
                                     Date start)
            throws Exception {
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal) session.getAttribute("sessionKey");
        session.setAttribute("time", new Time());
        PersonTimeActionForm2 ptaf = new PersonTimeActionForm2();
        Collection<Activity> activities = lookupPersonBean().getPersonActivities(key);
        Collection<IdName> taskPairs = new ArrayList<IdName>();
        boolean first = true;
        for (Activity activity: activities) {
            String pathName = activity.getProjectPathName() + activity.toString();
            taskPairs.add(new IdName(activity.getId(), pathName));
            Collection<IdName> statePairs = new ArrayList<IdName>();
            for (State state: lookupStateBean().findStates(key, activity.getTaskStateMachine())) {
                statePairs.add(new IdName(state.getId(), state.toString()));
            }
            ptaf.add(activity.getPercentageComplete(), activity.getRemainingDuration_min(), statePairs);
            if (first) {
                session.setAttribute("statePairs", statePairs);
                first = false;
            }
        }
        Collection completeIntegerStrings = new ArrayList();
        for (int j = 0; j <= 100; j+=5)
            completeIntegerStrings.add(new IntegerString(new Integer(j), Integer.toString(j)));
        session.setAttribute("taskPairs", taskPairs);
        session.setAttribute("completePairs", completeIntegerStrings);
        session.setAttribute("personTimeActionForm2", ptaf);
        session.setAttribute("hours", NodeUtil.getInstance().getHours());
        session.setAttribute("durationDays", NodeUtil.getInstance().getDurationDays());
        session.setAttribute("durationHours", NodeUtil.getInstance().getDurationHours());
        session.setAttribute("minutes", NodeUtil.getInstance().getMinutes());
        // setup default values
        TimeActionForm timeActionForm = new TimeActionForm();
        Iterator<Activity> iter = activities.iterator();
        if (iter.hasNext()) {
            Activity activity = iter.next();
            timeActionForm.setActivityId(activity.getId());
            timeActionForm.setStateId(activity.getState().getId());
            timeActionForm.setPercentageComplete(activity.getPercentageComplete());
            timeActionForm.setDurationTotalMins(activity.getRemainingDuration_min());
        }
        timeActionForm.setStopDate(new Date());
        timeActionForm.setStartDate(start); // after stop in case not today!
        session.setAttribute("timeActionForm", timeActionForm);
    }

    @Override
    public ActionForward showCreate(ActionMapping mapping,
                                    ActionForm form,
                                    HttpServletRequest request,
                                    HttpServletResponse response) throws Exception {
        Long nodeId = (Long)request.getAttribute("nodeId");
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Person person = new Person();
        person.setParentNode(lookupNodeBean().findNode(key, nodeId));
        session.setAttribute("person", person);
        PersonActionForm personAF = new PersonActionForm();
        createContactDetails(key, personAF);
        session.setAttribute("personAF", personAF);
        return mapping.findForward("ACTION_EDIT");
    }

    @Override
    public ActionForward showEdit(ActionMapping mapping,
                                  ActionForm form,
                                  HttpServletRequest request,
                                  HttpServletResponse response) throws Exception {
        Long nodeId = (Long)request.getAttribute("nodeId");
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Person person = lookupPersonBean().findPerson(key, nodeId);
        session.setAttribute("person", person);
        PersonActionForm personAF = new PersonActionForm();
        editContactDetails(key, person, personAF);
        session.setAttribute("personAF", personAF);
        return mapping.findForward("ACTION_EDIT");
    }

    @Override
    public ActionForward edit(ActionMapping mapping,
                              ActionForm form,
                              HttpServletRequest request,
                              HttpServletResponse response) throws Exception {
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Long nodeId;
        if (request.getParameter("btnSubmit").equals("OK")) {
            Person person = (Person)session.getAttribute("person");
            ((PersonActionForm)form).extractPerson(key, person);
            if (person.getId() != null) {
                lookupPersonBean().editPerson(key, person);
            }
            else {
                person = lookupPersonBean().createPerson(key, person);
            }
            nodeId = person.getId();
        }
        // Cancel simply displays the original node again
        else {
            nodeId = (Long)session.getAttribute("nodeId");
        }
        request.setAttribute("nodeId", nodeId);
        return mapping.findForward("ACTION_SUCCESS");
    }

    private PersonLocal lookupPersonBean() {
        try {
            Context c = new InitialContext();
            return (PersonLocal) c.lookup("java:comp/env/PersonBean");
        } catch (NamingException ne) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    private NodeLocal lookupNodeBean() {
        try {
            Context c = new InitialContext();
            return (NodeLocal) c.lookup("java:comp/env/NodeBean");
        } catch (NamingException ne) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    private SearchLocal lookupSearchBean() {
        try {
            Context c = new InitialContext();
            return (SearchLocal) c.lookup("java:comp/env/SearchBean");
        } catch (NamingException ne) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    private StateLocal lookupStateBean() {
        try {
            Context c = new InitialContext();
            return (StateLocal) c.lookup("java:comp/env/StateBean");
        } catch (NamingException ne) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

}
